/**
 * Copyright ©2016-2020 northkingbpo Corporation, All Rights Reserved
 * http://www.northkingbpo.net/
 */
package profile.hujia.log.analysis.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import profile.hujia.log.analysis.common.ConstantVariable;
import profile.hujia.log.analysis.data.LogDataService;
import profile.hujia.log.analysis.data.LogDataServiceImpl;
import profile.hujia.log.analysis.domain.LogInfo;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * class info
 *
 * @author hujia
 * @date 2018/12/17 12:30
 */
@Slf4j
@Service
public class ReadIntoMemoryServiceImpl implements ReadIntoMemoryService {

    @Value("${hujia.log.path}")
    private String path;
    @Value("${hujia.log.key.stopWatchBegin}")
    private String stopWatchBegin;
    @Value("${hujia.log.key.stopWatchEnd}")
    private String stopWatchEnd;
    @Value("${hujia.log.key.millisBegin}")
    private String millisBegin;
    @Value("${hujia.log.key.millisEnd}")
    private String millisEnd;
    @Value("${hujia.log.timeLen}")
    private int timeLen;
    @Value("${hujia.log.key.resultBegin}")
    private String resultBegin;
    @Value("${hujia.log.key.resultEnd}")
    private String resultEnd;

    private File file;
    private FileInputStream stream;
    private InputStreamReader streamReader;
    private BufferedReader reader;

    @Override
    public void init() throws Exception {
        file = new File(path);
        if (!file.exists()) {
            throw new Exception("no file !");
        }
        stream = new FileInputStream(file);
        streamReader = new InputStreamReader(stream);
        reader = new BufferedReader(streamReader);
    }

    @Override
    public void close() throws Exception {
        reader.close();
        streamReader.close();
        stream.close();
        file.delete();
    }

    @Override
    public LogDataService readIntoMap() throws Exception {
        LogDataService logDataService = new LogDataServiceImpl();
        String line;
        int pos = -1;
        while ((line = reader.readLine()) != null && ((pos = line.indexOf(ConstantVariable.BEGIN_TAG)) < 0)) ;
        if (line == null || pos < 0) {
            return null;
        }
        pos = line.indexOf(ConstantVariable.BEGIN_SEPARATOR,pos);
        logDataService.setTitle(line.substring(pos + 1));
        while ((line = reader.readLine()) != null) {
            if (line.contains(ConstantVariable.END_TAG)) {
                return logDataService;
            }
            LogInfo info = readInto(line);
            if (info != null) {
                logDataService.put(info.getRole(), info);
            }
        }
        return null;
    }

    private LogInfo readInto(String line) throws Exception {
        LogInfo info = new LogInfo();
        int posRoleName = line.indexOf(ConstantVariable.LOG_ROLE_NAME);
        int posCostTime = line.indexOf(ConstantVariable.LOG_COST_TIME);
        int posResult = line.lastIndexOf(ConstantVariable.LOG_RESULT);
        if (posRoleName == -1 || posCostTime == -1 || posResult == -1) {
            return null;
        }
        int begin = line.indexOf(stopWatchBegin, posRoleName);
        int end = line.indexOf(stopWatchEnd, begin + 1);
        String roleName = line.substring(begin + 1, end);
        begin = line.indexOf(millisBegin, posCostTime);
        end = line.indexOf(millisEnd, begin + 1);
        String costTime = line.substring(begin + 1, end).trim();
        String currentDate = line.substring(0, timeLen);
        begin = line.indexOf(resultBegin, posResult);
        end = line.indexOf(resultEnd, begin + 1);
        String result = line.substring(begin + 1, end);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date date = sdf.parse(currentDate);
        info.setCostTime(Long.parseLong(costTime));
        info.setRole(roleName);
        info.setOccurrenceTime(date);
        info.setHaveData(Boolean.parseBoolean(result));
        return info;
    }
}
